//--------------------------------------------------------------------------------------------
//
//  : 
//      Component name  : fpmul_stage4
//      Author          : 
//      Company         : 
//
//      Description     : 
//
//
//--------------------------------------------------------------------------------------------


module FPmul_stage4(EXP_neg, EXP_out_round, EXP_pos, SIGN_out, SIG_out_round, clk, isINF_tab, isNaN, isZ_tab, FP_Z);
   input         EXP_neg;
   input [7:0]   EXP_out_round;
   input         EXP_pos;
   input         SIGN_out;
   input [27:0]  SIG_out_round;
   input         clk;
   input         isINF_tab;
   input         isNaN;
   input         isZ_tab;
   output [31:0] FP_Z;
   reg [31:0]    FP_Z;
   
   
   wire [7:0]    EXP_out;
   wire [31:0]   FP;
   wire          SIG_isZ;
   wire [22:0]   SIG_out;
   wire [27:0]   SIG_out_norm2;
   reg           isINF;
   wire          isZ;
   
   assign SIG_out = SIG_out_norm2[25:3];
   
   assign SIG_isZ = (((SIG_out_norm2[26:3] == 24'h000000) | (EXP_neg == 1'b1 & EXP_out[7] == 1'b1))) ? 1'b1 : 
                    1'b0;
   
   
   always @(isZ or isINF_tab or EXP_pos or EXP_out)
      if (isZ == 1'b0)
      begin
         if (isINF_tab == 1'b1)
            isINF <= 1'b1;
         else if (EXP_out == 8'hFF)
            isINF <= 1'b1;
         else if ((EXP_pos == 1'b1) & (EXP_out[7] == 1'b0))
            isINF <= 1'b1;
         else
            isINF <= 1'b0;
      end
      else
         isINF <= 1'b0;
   
   
   always @(posedge clk)
      
         FP_Z <= FP;
   
   assign isZ = SIG_isZ | isZ_tab;
   
   
   FPnormalize #(.SIG_width(28)) I1(.SIG_in(SIG_out_round), .EXP_in(EXP_out_round), .SIG_out(SIG_out_norm2), .EXP_out(EXP_out));
   
   PackFP I3(.SIGN(SIGN_out), .EXP(EXP_out), .SIG(SIG_out), .isNaN(isNaN), .isINF(isINF), .isZ(isZ), .FP(FP));
   
endmodule
